package com.atguigu.ssyx.activity.service.impl;

import com.atguigu.ssyx.activity.mapper.CouponRangeMapper;
import com.atguigu.ssyx.activity.mapper.CouponUseMapper;
import com.atguigu.ssyx.client.product.ProductFeignClient;
import com.atguigu.ssyx.enums.CouponRangeType;
import com.atguigu.ssyx.enums.CouponStatus;
import com.atguigu.ssyx.model.activity.CouponInfo;
import com.atguigu.ssyx.activity.mapper.CouponInfoMapper;
import com.atguigu.ssyx.activity.service.CouponInfoService;
import com.atguigu.ssyx.model.activity.CouponRange;
import com.atguigu.ssyx.model.activity.CouponUse;
import com.atguigu.ssyx.model.order.CartInfo;
import com.atguigu.ssyx.model.product.Category;
import com.atguigu.ssyx.model.product.SkuInfo;
import com.atguigu.ssyx.vo.activity.CouponRuleVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 优惠券信息 服务实现类
 * </p>
 *
 * @author lqh
 * @since 2023-09-26
 */
@Service
public class CouponInfoServiceImpl extends ServiceImpl<CouponInfoMapper, CouponInfo> implements CouponInfoService {


    @Autowired
    private CouponRangeMapper couponRangeMapper;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private CouponUseMapper couponUseMapper;

    @Override
    public IPage<CouponInfo> selectPageCouponInfo(Long page, Long limit) {
        Page<CouponInfo> page1 = new Page<>(page, limit);
        //实体类 中 购物卷类型  还有使用范围 都是枚举类型 是一个枚举类型
        IPage<CouponInfo> couponInfoIPage = baseMapper.selectPage(page1, null);
        //同样是封装了枚举的类型 getRecords方法 获取当前页的集合数据
        List<CouponInfo> records = couponInfoIPage.getRecords();

        records.stream().forEach(item -> {
            item.setCouponTypeString(item.getCouponType().getComment());
            CouponRangeType rangeType = item.getRangeType();
            if (rangeType != null) {
                item.setRangeTypeString(rangeType.getComment());
            }
        });

        return page1;


    }

    //根据Id查询优惠政策
    @Override
    public CouponInfo getCouponInfo(Long id) {
        CouponInfo couponInfo = baseMapper.selectById(id);
        couponInfo.setCouponTypeString(couponInfo.getCouponType().getComment());
        //使用范围
        if (couponInfo.getRangeType() != null) {
            couponInfo.setRangeTypeString(couponInfo.getRangeType().getComment());
        }

        return couponInfo;
    }

    //根据优惠卷Id查询规则数据
    @Override
    public Map<String, Object> findCouponRuleList(Long id) {
        //前端传来的是coupon_id的值
        //1.根据优惠卷ID 得到优惠卷信息 coupon_info
        CouponInfo couponInfo = baseMapper.selectById(id);

        //2.根据优惠卷ID 查询coupon_range 查询里面对应的coupon——range_id
        List<CouponRange> couponRangeList = couponRangeMapper.selectList(
                new LambdaQueryWrapper<CouponRange>().eq(CouponRange::getCouponId, id)
        );

        //获取到所有的range_id值
        //如果规则类型SKU range_id range_id就是SkuId值
        //如果规则类型 CATEGORY range_id就是分类Id值
        List<Long> rangeIdList =
                couponRangeList.stream().map(CouponRange::getRangeId).collect(Collectors.toList());

        Map<String, Object> map = new HashMap<>();

        //之前错误 少了! 判断错误 没进来封装
        if (!CollectionUtils.isEmpty(rangeIdList)) {
            //如果规则类型SKU range_id range_id就是SkuId值
            if (couponInfo.getRangeType() == CouponRangeType.SKU) {
                //远程调用
                List<SkuInfo> skuInfoList = productFeignClient.findSkuInfoList(rangeIdList);
                map.put("skuInfoList", skuInfoList);
            } else if (couponInfo.getRangeType() == CouponRangeType.CATEGORY) {
                //分类的处理
                //远程调用
                List<Category> categoryList =
                        productFeignClient.getCategoryList(rangeIdList);

                map.put("categoryList", categoryList);
            }
        }
        return map;
        //分别判断 封装不同的数据 如果是SKU 得到SKUId 远程调用根据多个skuId值获取对应sku信息
        //如果说规则类型是分类 得到分类Id 远程调用根据多个分类Id值获取对应的分类信息
    }

    //5 添加优惠卷规则数据
    @Override
    public void saveCouponRule(CouponRuleVo couponRuleVo) {
        //根据优惠卷Id(coupon_id)先删除  coupon_rang表中的信息
        //在修改基本信息
        //最后在添加

        //因为表中 的rang_id 更具rang_type 对应不同的rang_id 就可能存在不同类型 相同的rang_id

        //根据优惠卷 id删除规则数据
        couponRangeMapper.delete(
                new LambdaQueryWrapper<CouponRange>()
                        .eq(CouponRange::getCouponId, couponRuleVo.getCouponId())
        );

        //更新优惠卷基本信息
        CouponInfo couponInfo = baseMapper.selectById(couponRuleVo.getCouponId());
        couponInfo.setRangeType(couponRuleVo.getRangeType());
        couponInfo.setConditionAmount(couponRuleVo.getConditionAmount());
        couponInfo.setAmount(couponRuleVo.getAmount());
        couponInfo.setRangeDesc(couponRuleVo.getRangeDesc());

        baseMapper.updateById(couponInfo);
        //添加优惠卷新规则数据
        List<CouponRange> couponRangeList = couponRuleVo.getCouponRangeList();
        for (CouponRange couponRange : couponRangeList) {
            //设置优惠卷Id
            couponRange.setCouponId(couponRuleVo.getCouponId());
            couponRangeMapper.insert(couponRange);
        }
    }

    //删除优惠卷列表
    @Override
    public void removeAndRang(Long id) {
        baseMapper.deleteById(id);
        //删除coupon_range
        LambdaQueryWrapper<CouponRange> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CouponRange::getCouponId, id);
        couponRangeMapper.delete(wrapper);
    }

    //根据skuId + userId查询优惠卷信息
    @Override
    public List<CouponInfo> findCouponInfoList(Long skuId, Long userId) {
        //得到sku信息 远程调用
        SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);

        //根据条件查询 skuId + 分类id + userId
        List<CouponInfo> couponInfoList =
                baseMapper.selectCouponInfoList(skuInfo.getId(), skuInfo.getCategoryId(), userId);

        return couponInfoList;

    }

    //获取购物车可以使用的优惠卷列表
    @Override
    public List<CouponInfo> findCartCouponInfo(List<CartInfo> cartInfoList, Long userId) {

        //根据userId获取用户全部优惠卷
        //coupon_use  coupon_info
        List<CouponInfo> userAllCouponInfoList = baseMapper.selectCartCouponInfoList(userId);

        if (CollectionUtils.isEmpty(userAllCouponInfoList)) {
            return new ArrayList<CouponInfo>();
        }

        //2.从第一步骤返回list集合中 获取所有优惠卷id列表
        List<Long> couponIdList = userAllCouponInfoList.stream().map(couponInfo -> couponInfo.getId())
                .collect(Collectors.toList());

        //3.查询优惠卷对应的范围
        //couponRangList
        LambdaQueryWrapper<CouponRange> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CouponRange::getCouponId, couponIdList);
        List<CouponRange> couponRangeList = couponRangeMapper.selectList(wrapper);

        //4.获取优惠卷Id 对应skuId列表
        //优惠卷id进行分组 得到map集合
        //Map<Long,List<Long>>
        Map<Long, List<Long>> couponIdToSkuIdMap =
                this.findCouponIdToSkuIdMap(cartInfoList, couponRangeList);

        //5.遍历全部优惠卷集合 判断优惠卷类型
        //全程通用 sku 和 分类
        BigDecimal reduceAmount = new BigDecimal(0);
        for (CouponInfo couponInfo : userAllCouponInfoList) {
            if (CouponRangeType.ALL == couponInfo.getRangeType()) {
                //全场通用
                //全场通用
                //判断是否满足优惠使用门槛
                //计算购物车商品的总价
                BigDecimal totalAmount = computeTotalAmount(cartInfoList);
                if (totalAmount.subtract(couponInfo.getConditionAmount()).doubleValue() >= 0) {
                    couponInfo.setIsSelect(1);
                }
            } else {
                //优惠卷id获取对应skuId列表
                List<Long> skuIdList
                        = couponIdToSkuIdMap.get(couponInfo.getId());

                //满足使用范围购物项
                List<CartInfo> currentCartInfoList =
                        cartInfoList.stream().filter(cartInfo -> skuIdList.contains(cartInfo.getSkuId()))
                                .collect(Collectors.toList());


            }

        }

        return null;
    }

    private Map<Long, List<Long>> findCouponIdToSkuIdMap(List<CartInfo> cartInfoList, List<CouponRange> couponRangeList) {
        Map<Long, List<Long>> couponIdToSkuIdMap = new HashMap<>();

        //数据处理 根据优惠卷id分组
        Map<Long, List<CouponRange>> couponRangeToListMap = couponRangeList.stream()
                .collect(Collectors
                        .groupingBy(couponRange -> couponRange.getCouponId()));
        //遍历map集合
        Iterator<Map.Entry<Long, List<CouponRange>>> iterator =
                couponRangeToListMap.entrySet().iterator();
        while (iterator.hasNext()) {

            Map.Entry<Long, List<CouponRange>> next = iterator.next();
            Long couponId = next.getKey();
            List<CouponRange> rangeList = next.getValue();

            //得到sku的部分 创建集合
            Set<Long> skuIdSet = new HashSet<>();

            for (CartInfo cartInfo : cartInfoList) {
                //得到每个购物项
                for (CouponRange couponRange : rangeList) {
                    //判断 是否是sku
                    if (couponRange.getRangeType() == CouponRangeType.SKU
                            && couponRange.getRangeId().longValue() == cartInfo.getSkuId().longValue()) {
                        skuIdSet.add(cartInfo.getSkuId());
                    } else if (couponRange.getRangeType() == CouponRangeType.CATEGORY
                            && couponRange.getCouponId().longValue() == cartInfo.getCategoryId().longValue()) {
                        skuIdSet.add(cartInfo.getSkuId());
                    } else {
                        //全场通用
                    }
                }
            }
            couponIdToSkuIdMap.put(couponId, new ArrayList<>(skuIdSet));
        }
        return couponIdToSkuIdMap;
    }

    private BigDecimal computeTotalAmount(List<CartInfo> cartInfoList) {
        BigDecimal total = new BigDecimal("0");
        for (CartInfo cartInfo : cartInfoList) {
            //是否选中
            if (cartInfo.getIsChecked().intValue() == 1) {
                BigDecimal itemTotal = cartInfo.getCartPrice().multiply(new BigDecimal(cartInfo.getSkuNum()));
                total = total.add(itemTotal);
            }
        }
        return total;
    }

    //获取购物车对应优惠卷的部分
    @Override
    public CouponInfo findRangeSkuIdList(List<CartInfo> cartInfoList, Long couponId) {
        //根据优惠劵id基本信息的查询
        CouponInfo couponInfo = baseMapper.selectById(couponId);

        if (couponInfo == null) {
            return null;
        }
        //根据couponId查询CouponRange数据
        List<CouponRange> couponRangeList = couponRangeMapper.selectList(
                new LambdaQueryWrapper<CouponRange>().eq(CouponRange::getCouponId, couponId)
        );

        //对应的sku信息
        Map<Long, List<Long>> couponIdToSkuIdMap =
                this.findCouponIdToSkuIdMap(cartInfoList, couponRangeList);

        //遍历map集合 得到val值 封装到新的couponInfo对象中
        List<Long> skuIdList = couponIdToSkuIdMap.entrySet().iterator().next().getValue();

        couponInfo.setSkuIdList(skuIdList);

        return couponInfo;
    }

    //更新优惠卷使用状态
    @Override
    public void updateCouponInfoUserStatus(Long couponId, Long userId, Long orderId) {
        //根据couponId查询优惠卷信息
        CouponUse couponUse = couponUseMapper.selectOne(
                new LambdaQueryWrapper<CouponUse>()
                        .eq(CouponUse::getCouponId, couponId)
                        .eq(CouponUse::getUserId, userId)
                        .eq(CouponUse::getOrderId, orderId)
        );
        //设置修改值
        couponUse.setCouponStatus(CouponStatus.USED);
        //调用方法修改
        couponUseMapper.updateById(couponUse);
    }
}
